%{
  #include <stdio.h>
  #include "y.tab.h"
  #include "table.h"
  #include "action.h"

  struct table * tab;

%}

%union{
  int i;
  char* s;
  float f;
  struct var *v;
 }

%token AND OR CLASS IF THEN ELSE END WHILE DO DEF LEQ GEQ 
%token FOR TO RETURN IN NEQ
%token <i> INT
%token <s> STRING ID
%token <f> FLOAT
%type <v> primary multiplicative_expr additive_expr comp_expr expr exprs
%type <v> stmt lhs stmts
%left '*' 
%left '/'
%left '+' '-'
%left '<' '>' LEQ GEQ EQ
%left AND OR
%%
program		:  topstmts opt_terms
;
topstmts        :      
| topstmt
| topstmts terms topstmt
;
topstmt	        : CLASS ID term stmts END 
                | CLASS ID '<' ID term stmts END
| stmt {DebugAfficher($1);}
;

stmts	        : /* none */
| stmt {$$ = $1;}
| stmts terms stmt {$$ = actionCONCATE(tab,$1,$3);}
;

stmt: IF expr THEN stmts terms END {$$ = actionIF(tab,$2,$4);}
| IF expr THEN stmts terms ELSE stmts terms END /*{$$ = actionIFELSE(tab,$2,$4,$7;}*/
| FOR ID IN expr TO expr term stmts terms END
| WHILE expr DO term stmts terms END {$$ = actionWHILE(tab,$2,$5);}
| lhs '=' expr {$$=actionAFFECTATION(tab,$1,$3)}
| RETURN expr
| DEF ID opt_params term stmts terms END
; 

opt_params      : /* none */
                | '(' ')'
                | '(' params ')'
;
params          : ID ',' params
                | ID
; 
lhs             : ID {$$=existe(tab,$1); if($$==NULL){$$=creerVar(tab,$1,UNDEF);}}
                | ID '.' primary
                | ID '(' exprs ')'
;
exprs           : exprs ',' expr
| expr {$$ = $1;}
;
primary         : lhs {$$=actionCHARGER(tab,$1);}
| STRING {$$=creerVar(tab,NULL,STRING);}
| FLOAT {$$=creerVar(tab,NULL,FLOAT); actionFLOAT($$,$1);}
| INT {$$=creerVar(tab,NULL,INTEGER);actionINT($$,$1);}
| '(' expr ')' {$$ = $2;}
;
expr            : expr AND comp_expr {$$ = actionANDOR(tab,$1,$3,"and");}
                | expr OR comp_expr {$$ = actionANDOR(tab,$1,$3,"or");}
| comp_expr {$$ = $1; }
;
comp_expr       : additive_expr '<' additive_expr {$$ = actionCOMPARAISON(tab,$1,$3,"slt");}
| additive_expr '>' additive_expr {$$ = actionCOMPARAISON(tab,$1,$3,"sgt");}
| additive_expr LEQ additive_expr {$$ = actionCOMPARAISON(tab,$1,$3,"use");}
| additive_expr GEQ additive_expr {$$ = actionCOMPARAISON(tab,$1,$3,"sge");}
| additive_expr EQ additive_expr {$$ = actionCOMPARAISON(tab,$1,$3,"eq");}
| additive_expr NEQ additive_expr {$$ = actionCOMPARAISON(tab,$1,$3,"ne");}
| additive_expr {$$ = $1;}
;
additive_expr   : multiplicative_expr {$$ = $1;}
| additive_expr '+' multiplicative_expr {$$=actionADD(tab,$1,$3);}
                | additive_expr '-' multiplicative_expr {$$=actionSUB(tab,$1,$3);}
;
multiplicative_expr : multiplicative_expr '*' primary {$$=actionMUL(tab,$1,$3);}
| multiplicative_expr '/' primary {$$=actionDIV(tab,$1,$3);}
| primary {$$ = $1;}
;
opt_terms	: /* none */
		| terms
		;

terms		: terms ';'
                | terms '\n'
		| ';'
                | '\n'
		;
term            : ';'
                | '\n'
;
%%
int main() {
  tab=initTable();
  yyparse();
  supprTable(tab);
  return 0;
}
